﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;

namespace VGS
{
    public partial class StatisticsForm : Form
    {
        #region Constructor
        public StatisticsForm()
        {
            InitializeComponent();
        }
        #endregion

        #region Event handling
        private void Statistics_Load(object sender, EventArgs e)
        {
            VolleyMatch vm = VolleyMatch.Instance;

            // Add the teams' names to the combo box
            comboBoxTeam.Items.Add("HT: " + vm.HomeTeam.Name);
            comboBoxTeam.Items.Add("AT: " + vm.AwayTeam.Name);

            comboBoxTeam.SelectedIndex = 0;

            // Add the sets
            foreach (Set set in vm.Sets)
            {
                // Make sure the set has started
                if (set.Status != SetStatus.SET_WARMUP)
                    comboBoxSet.Items.Add("Set " + set.Number);
            }
            comboBoxSet.SelectedIndex = 0;
        }

        private void comboBoxTeam_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateStatistics();
        }

        private void comboBoxSet_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateStatistics();
        }
        #endregion

        #region Custom methods
        private void UpdateStatistics()
        {
            // 0 = Both teams
            // 1 = Home team
            // 2 = Away team
            int team = comboBoxTeam.SelectedIndex;

            // 0 = All sets
            // 1 = Set 1
            // 2 = ...
            int setId = comboBoxSet.SelectedIndex;

            if (setId == -1) setId = 0;

            // Remove all existing data
            listViewAttack.Items.Clear();
            listViewDefense.Items.Clear();
            listViewServe.Items.Clear();
            listViewTotal.Items.Clear();

            switch (team)
            {
                case 1:
                    UpdateStatisticsForTeam(TeamEnum.HOME_TEAM, setId);
                    break;
                case 2:
                    UpdateStatisticsForTeam(TeamEnum.AWAY_TEAM, setId);
                    break;
                default:
                    UpdateStatisticsForBothTeams(setId);
                    break;
            }
        }

        /// <summary>
        /// Shows statistics from both teams and the specified set. If setId == 0,
        /// statistics from all sets will be shown
        /// </summary>
        /// <param name="setId">The set ID</param>
        private void UpdateStatisticsForBothTeams(int setId)
        {
            VolleyMatch vm = VolleyMatch.Instance;

            // Show statistics for all sets
            if (setId == 0)
            {
                foreach (Player p in vm.HomeTeam.Players)
                {
                    foreach (KeyValuePair<int, PlayerStatistics> kvp in p.Stats)
                    {
                        listViewAttack.Items.Add(kvp.Value.AttackPoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewDefense.Items.Add(kvp.Value.DefensePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewServe.Items.Add(kvp.Value.ServePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewTotal.Items.Add(
                            (kvp.Value.AttackPoints+kvp.Value.DefensePoints+kvp.Value.ServePoints).ToString()).SubItems.Add(
                            p.Name + " (" + p.Shirt + ")");
                    }
                }
                foreach (Player p in vm.AwayTeam.Players)
                {
                    foreach (KeyValuePair<int, PlayerStatistics> kvp in p.Stats)
                    {
                        listViewAttack.Items.Add(kvp.Value.AttackPoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewDefense.Items.Add(kvp.Value.DefensePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewServe.Items.Add(kvp.Value.ServePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewTotal.Items.Add(
                            (kvp.Value.AttackPoints + kvp.Value.DefensePoints + kvp.Value.ServePoints).ToString()).SubItems.Add(
                            p.Name + " (" + p.Shirt + ")");
                    }
                }
                labelStats.Text = "Showing statistics for both teams and all started sets";
            }
            else
            {
                // LINQ: Select the players from both team's that have scored in the set with
                // id 'setId'
                var playersWithStats =
                    vm.HomeTeam.Players.Where(p => p.Stats.ContainsKey(setId))
                                       .Concat(
                    vm.AwayTeam.Players.Where(p => p.Stats.ContainsKey(setId)));

                foreach (Player p in playersWithStats)
                {
                    PlayerStatistics ps = p.Stats[setId]; // We know the setId key exists (see LINQ above)

                    listViewAttack.Items.Add(ps.AttackPoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewDefense.Items.Add(ps.DefensePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewServe.Items.Add(ps.ServePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewTotal.Items.Add(
                        (ps.AttackPoints + ps.DefensePoints + ps.ServePoints).ToString()).SubItems.Add(
                        p.Name + " (" + p.Shirt + ")");
                }

                labelStats.Text = "Showing statistics for both teams and set " + setId;
            }
        }

        /// <summary>
        /// Shows statistics for the specified team and set. If setId == 0, statistics
        /// will be based on all sets, otherwise on the setId
        /// </summary>
        /// <param name="team">The team</param>
        /// <param name="setId">The set ID</param>
        private void UpdateStatisticsForTeam(TeamEnum team, int setId)
        {
            VolleyMatch vm = VolleyMatch.Instance;
            Players players = null;

            switch (team)
            {
                case TeamEnum.HOME_TEAM:
                    players = vm.HomeTeam.Players;
                    if (setId == 0)
                        labelStats.Text = string.Format("Showing statistics for team {0} and all started sets", vm.HomeTeam.Name);
                    else
                        labelStats.Text = string.Format("Showing statistics for team {0} and set {1}", vm.HomeTeam.Name, setId);
                    break;
                case TeamEnum.AWAY_TEAM:
                    players = vm.AwayTeam.Players;
                    if (setId == 0)
                        labelStats.Text = string.Format("Showing statistics for team {0} and all started sets", vm.AwayTeam.Name);
                    else
                        labelStats.Text = string.Format("Showing statistics for team {0} and set {1}", vm.AwayTeam.Name, setId);
                    break;
            }
                
            // Show statistics for all sets
            if (setId == 0)
            {
                var playersWithStats = players.Where(p => p.Stats.Count > 0);

                foreach (Player p in playersWithStats)
                {
                    foreach (KeyValuePair<int, PlayerStatistics> kvp in p.Stats)
                    {
                        listViewAttack.Items.Add(kvp.Value.AttackPoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewDefense.Items.Add(kvp.Value.DefensePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewServe.Items.Add(kvp.Value.ServePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                        listViewTotal.Items.Add(
                        (kvp.Value.AttackPoints + kvp.Value.DefensePoints + kvp.Value.ServePoints).ToString()).SubItems.Add(
                        p.Name + " (" + p.Shirt + ")");
                    }
                }
            }
            // Show statistics for a specific set, with 'setId'
            else
            {
                // LINQ: Select the players which have stats associated with the specified set
                var playersWithStats = players.Where(p => p.Stats.ContainsKey(setId));

                foreach (Player p in playersWithStats)
                {
                    PlayerStatistics ps = p.Stats[setId];

                    listViewAttack.Items.Add(ps.AttackPoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewDefense.Items.Add(ps.DefensePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewServe.Items.Add(ps.ServePoints.ToString()).SubItems.Add(p.Name + " (" + p.Shirt + ")");
                    listViewTotal.Items.Add(
                    (ps.AttackPoints + ps.DefensePoints + ps.ServePoints).ToString()).SubItems.Add(
                    p.Name + " (" + p.Shirt + ")");
                }
            }
        }
        #endregion
    }
}
